#pragma semicolon 1
#include <sourcemod>
#include <ncs_rpg>

#define VERSION				"Beta 1.0.1"
#define MAX_RPG_CMDS		32
#define MAX_RPG_CMDS_SIZE	192

new Handle:hFWD_OnSkillUP = INVALID_HANDLE;

public Plugin:myinfo =
{
	name		= "[NCS RPG] Menu",
	author		= "[RUS] DiviX",
	description	= "[NCS RPG] Menu",
	version		= VERSION,
	url			= "N/A"
};

public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
	// Forwards
	hFWD_OnSkillUP = CreateGlobalForward("RPG_OnSkillUP", ET_Hook, Param_CellByRef, Param_CellByRef, Param_CellByRef, Param_CellByRef);
	
	// Natives
	CreateNative("OnSkillUP", Native_OnSkillUP);
	
	// Let plugin load.
	return APLRes_Success;
}

public OnPluginStart()
{
	RegConsoleCmd("sm_rpg", Command_RPG, "NCS RPG Menu");
	RegConsoleCmd("say", Command_Say);
	RegConsoleCmd("say_team", Command_Say);
	LoadTranslations("ncs_rpg/ncs_rpg.menu.phrases");
}

public Action:Command_RPG(client, args)
{
	if(IsValidPlayer(client))
		DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
	
	return Plugin_Handled;
}

public Action:Command_Say(client, args)
{
	if(IsValidPlayer(client))
	{
		decl String:buffer[MAX_RPG_CMDS+1][MAX_RPG_CMDS_SIZE];
		if(GetConfigValueString("advert", "cmds", buffer[MAX_RPG_CMDS], MAX_RPG_CMDS_SIZE))
		{
			new count = ExplodeString(buffer[MAX_RPG_CMDS], ",", buffer, MAX_RPG_CMDS, MAX_RPG_CMDS_SIZE);
			if(count > 0)
			{			
				GetCmdArgString(buffer[MAX_RPG_CMDS], MAX_RPG_CMDS_SIZE);
				StripQuotes(buffer[MAX_RPG_CMDS]);
				BreakString(buffer[MAX_RPG_CMDS], buffer[MAX_RPG_CMDS], MAX_RPG_CMDS_SIZE);
				
				for(new i = 0; i < count; i++)
				{
					if(StrEqual(buffer[i], buffer[MAX_RPG_CMDS], false))
					{
						DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
						if(GetConfigValue("advert", "hide", 0) > 0)
							return Plugin_Handled;
						
						return Plugin_Continue;
					}
				}
			}
		}
	}
	
	return Plugin_Continue;
}

public OnClientPutInServer(client)
{
	if(GetConfigValue("advert", "welcome", 1) > 0)
		if(IsValidPlayer(client))
			DisplayMenu(BuildMenuWelcome(client), client, MENU_TIME_FOREVER);
}

stock Handle:BuildMenuWelcome(client)
{
	decl String:display[64];
	new Handle:menu = CreateMenu(HandlerMenuWelcome);
	SetMenuTitle(menu, "%T", "Welcome To Server", client, VERSION);
	
	AddMenuItem(menu, "", " ", ITEMDRAW_SPACER);
	
	Format(display, sizeof(display), "%T", "Main menu", client);
	AddMenuItem(menu, "main", display);
	
	Format(display, sizeof(display), "%T", "What is an RPG?", client);
	AddMenuItem(menu, "rpg", display);
	
	//SetMenuExitBackButton(menu, false);
	//SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuWelcome(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[16];
		GetMenuItem(menu, param2, info, sizeof(info));
		if(StrEqual(info, "main"))
			DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
		else if(StrEqual(info, "rpg"))
			DisplayMenu(BuildMenuRPG(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuMain(client)
{
	decl String:display[64];
	new Handle:menu = CreateMenu(HandlerMenuMain);
	SetMenuTitle(menu, "%T", "Main menu title", client);
	
	Format(display, sizeof(display), "%T", "Upgrade", client);
	AddMenuItem(menu, "upgrade", display);
	
	Format(display, sizeof(display), "%T", "Sell", client);
	AddMenuItem(menu, "sell", display);
	
	Format(display, sizeof(display), "%T", "Statistics", client);
	AddMenuItem(menu, "stats", display);
	
	Format(display, sizeof(display), "%T", "Help", client);
	AddMenuItem(menu, "help", display);
	
	SetMenuExitBackButton(menu, false);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuMain(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[16];
		GetMenuItem(menu, param2, info, sizeof(info));
		if(StrEqual(info, "upgrade"))
			DisplayMenu(BuildMenuUpgrades(client), client, MENU_TIME_FOREVER);
		else if(StrEqual(info, "sell"))
			DisplayMenu(BuildMenuSell(client), client, MENU_TIME_FOREVER);
		else if(StrEqual(info, "stats"))
			DisplayMenu(BuildMenuStats(client), client, MENU_TIME_FOREVER);
		else if(StrEqual(info, "help"))
			DisplayMenu(BuildMenuHelp(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuUpgrades(client)
{
	decl String:display[MAX_SKILL_NAME_LENGTH+32], String:buffer[MAX_SKILL_NAME_LENGTH+1];
	new Handle:menu = CreateMenu(HandlerMenuUpgrades);
	SetMenuTitle(menu, "%T", "Upgrade title", client, GetCredits(client));
	
	for(new i = 0; i < GetSkillCount(); i++)
	{
		new maxlevel = GetSkillMaxLevel(i);
		new level = GetSkillLevel(client, i);
		GetSkillName(i, display, sizeof(display), client);
		if(level < maxlevel)
			Format(buffer, sizeof(buffer), "%T", "Skill cost", client, GetClientSkillCost(client, i));
		else
			Format(buffer, sizeof(buffer), "%T", "Not cost, max level", client);
		Format(display, sizeof(display), "%T", "Skill", client, level, maxlevel, display, buffer);
		IntToString(i, buffer, sizeof(buffer));
		AddMenuItem(menu, buffer, display, (level >= maxlevel)?ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT);
	}
	
	if(!GetMenuItemCount(menu))
	{
		Format(display, sizeof(display), "%T", "Skills are not available", client);
		AddMenuItem(menu, "none", display, ITEMDRAW_DISABLED);
	}
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuUpgrades(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[MAX_SKILL_NAME_LENGTH];
		GetMenuItem(menu, param2, info, sizeof(info));
		new index = StringToInt(info);
		new cost = GetClientSkillCost(client, index);
		if(GetCredits(client) >= cost)
		{
			new old_level = GetSkillLevel(client, index);
			new new_level = old_level+1; // api
			
			if(API_OnSkillUP(client, index, old_level, new_level) != Plugin_Handled)
			{
			
				SetCredits(client, GetCredits(client)-cost);
				SetSkillLevel(client, index, new_level);
				GetSkillName(index, info, sizeof(info), client);
				CPrintToChat(client, CPrefix, "You have raised the level of skill!", client, info, old_level, GetSkillLevel(client, index));
			}
		}
		else
			CPrintToChat(client, CPrefix, "Not enough credits!", client);
		
		DisplayMenuAtItem(BuildMenuUpgrades(client), client, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuSell(client)
{
	decl String:display[MAX_SKILL_NAME_LENGTH+32], String:buffer[16];
	new Handle:menu = CreateMenu(HandlerMenuSell);
	SetMenuTitle(menu, "%T", "Sell title", client, GetCredits(client));
	
	for(new i = 0; i < GetSkillCount(); i++)
	{
		new level = GetSkillLevel(client, i);
		if(level <= 0)
			continue;
		
		GetSkillName(i, display, sizeof(display), client);
		Format(display, sizeof(display), "%T", "Sell skill", client, level, GetSkillMaxLevel(i), display, RoundToFloor(GetSkillCost(i, level)*GetConfigValue("skills", "save_percent", 75)/100.0), GetSkillCost(i, level));
		IntToString(i, buffer, sizeof(buffer));
		AddMenuItem(menu, buffer, display, ITEMDRAW_DEFAULT);
	}
	
	if(!GetMenuItemCount(menu))
	{
		Format(display, sizeof(display), "%T", "Skills are not available", client);
		AddMenuItem(menu, "none", display, ITEMDRAW_DISABLED);
	}
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuSell(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[MAX_SKILL_NAME_LENGTH];
		GetMenuItem(menu, param2, info, sizeof(info));
		new skillid = StringToInt(info);
		new old_level = GetSkillLevel(client, skillid);
		if(old_level > 0)
		{
			new new_level = old_level-1; // api
			new save = RoundToFloor(GetSkillCost(skillid, old_level)*GetConfigValue("skills", "save_percent", 75)/100.0);
			if(API_OnSkillUP(client, skillid, old_level, new_level) != Plugin_Handled)
			{
				SetCredits(client, GetCredits(client)+save);
				SetSkillLevel(client, skillid, new_level);
				GetSkillName(skillid, info, sizeof(info), client);
				CPrintToChat(client, CPrefix, "You have sold the level of skill!", client, info, old_level, GetSkillLevel(client, skillid));
			}
		}		
		DisplayMenuAtItem(BuildMenuSell(client), client, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuStats(client)
{
	decl String:display[64];
	new Handle:menu = CreateMenu(HandlerMenuStats);
	SetMenuTitle(menu, "%T", "Stats title", client, client);
	
	if(GetConfigValue("player", "reset", 1))
	{
		Format(display, sizeof(display), "%T", "Reset stats", client);
		AddMenuItem(menu, "reset", display);
	}
	
	if(GetConfigValue("player", "playerinfo", 2) > 0)
	{
		Format(display, sizeof(display), "%T", "Info about players", client);
		AddMenuItem(menu, "info", display);
	}
	
	Format(display, sizeof(display), "%T", "Your level", client, GetLevel(client));
	AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
		
	Format(display, sizeof(display), "%T", "Your XP", client, GetXP(client), GetReqXP(client));
	AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
	
	Format(display, sizeof(display), "%T", "Your credits", client, GetCredits(client));
	AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuStats(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[8];
		GetMenuItem(menu, param2, info, sizeof(info));
		if(StrEqual(info, "reset"))
			DisplayMenu(BuildMenuReset(client), client, MENU_TIME_FOREVER);
		else if(StrEqual(info, "info"))
			DisplayMenu(BuildMenuInfoChoosePlayer(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuReset(client)
{
	decl String:display[16];
	new Handle:menu = CreateMenu(HandlerMenuReset);
	SetMenuTitle(menu, "%T", "Reset title", client, client);
	
	AddMenuItem(menu, " ", " ", ITEMDRAW_SPACER);
	
	Format(display, sizeof(display), "%T", "Yes", client);
	AddMenuItem(menu, "yes", display);
	
	Format(display, sizeof(display), "%T", "No", client);
	AddMenuItem(menu, "no", display);
	
	//SetMenuExitBackButton(menu, true);
	//SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuReset(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[8];
		GetMenuItem(menu, param2, info, sizeof(info));
		if(StrEqual(info, "yes"))
		{
			ResetPlayer(client);
			DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
		}
		else
			DisplayMenu(BuildMenuStats(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuStats(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuInfoChoosePlayer(client)
{
	new Handle:menu = CreateMenu(HandlerMenuInfoChoosePlayer);
	SetMenuTitle(menu, "%T", "Choose a player:", client);
	
	AddMenuPlayers(menu, client);
	
	if(GetMenuItemCount(menu) < 1)
	{
		decl String:display[64];
		Format(display, sizeof(display), "%T", "On the server, there are no other players!", client);
		AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
	}
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuInfoChoosePlayer(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[16];
		GetMenuItem(menu, param2, info, sizeof(info));
		new target = GetClientOfUserId(StringToInt(info));
		if(IsValidPlayer(target))
			DisplayMenu(BuildMenuPlayerInfo(client, target), client, MENU_TIME_FOREVER);
		else
		{
			CPrintToChat(client, CPrefix, "Invalid player", client);
			DisplayMenu(BuildMenuInfoChoosePlayer(client), client, MENU_TIME_FOREVER);
		}
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuStats(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuPlayerInfo(client, target)
{
	decl String:display[MAX_SKILL_NAME_LENGTH+32];
	new Handle:menu = CreateMenu(HandlerMenuPlayerInfo);
	SetMenuTitle(menu, "%T", "Stats title", client, target);
	
	Format(display, sizeof(display), "%T", "Level:", client, GetLevel(target));
	AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
		
	Format(display, sizeof(display), "%T", "XP:", client, GetXP(target), GetReqXP(target));
	AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
	
	Format(display, sizeof(display), "%T", "Credits:", client, GetCredits(target));
	AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
	
	if(GetConfigValue("player", "playerinfo", 2) > 1)
	{
		for(new i = 0; i < GetSkillCount(); i++)
		{
			GetSkillName(i, display, sizeof(display), client);
			Format(display, sizeof(display), "%T", "Player skill info", client, GetSkillLevel(target, i), GetSkillMaxLevel(i), display);
			AddMenuItem(menu, "", display, ITEMDRAW_DISABLED);
		}
	}
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuPlayerInfo(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuInfoChoosePlayer(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuHelp(client)
{
	decl String:display[MAX_SKILL_DESC_LENGTH];
	new Handle:menu = CreateMenu(HandlerMenuHelp);
	SetMenuTitle(menu, "%T%s", "Help", client, ":");
	
	Format(display, sizeof(display), "%T", "Description of skills", client);
	AddMenuItem(menu, "desc", display);
	
	Format(display, sizeof(display), "%T", "What is an RPG?", client);
	AddMenuItem(menu, "rpg", display);
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuHelp(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[8];
		GetMenuItem(menu, param2, info, sizeof(info));
		if(StrEqual(info, "desc"))
			DisplayMenu(BuildMenuDesc(client), client, MENU_TIME_FOREVER);
		else if(StrEqual(info, "rpg"))
			DisplayMenu(BuildMenuRPG(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuMain(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuDesc(client)
{
	decl String:display[MAX_SKILL_NAME_LENGTH], String:buffer[MAX_SKILL_NAME_LENGTH+1];
	new Handle:menu = CreateMenu(HandlerMenuDesc);
	SetMenuTitle(menu, "%T", "Choose a skill:", client);
	
	for(new i = 0; i < GetSkillCount(); i++)
	{
		GetSkillName(i, display, sizeof(display), client);
		IntToString(i, buffer, sizeof(buffer));
		AddMenuItem(menu, buffer, display);
	}
	
	if(!GetMenuItemCount(menu))
	{
		Format(display, sizeof(display), "%T", "Skills are not available", client);
		AddMenuItem(menu, "none", display, ITEMDRAW_DISABLED);
	}
	
	SetMenuExitBackButton(menu, true);
	SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuDesc(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Select)
	{
		decl String:info[MAX_SKILL_NAME_LENGTH+1];
		GetMenuItem(menu, param2, info, sizeof(info));
		DisplayMenu(BuildMenuDescSkill(client, StringToInt(info)), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuHelp(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuDescSkill(client, skillid)
{
	decl String:display[MAX_SKILL_DESC_LENGTH];
	new Handle:menu = CreateMenu(HandlerMenuDescSkill, MenuAction_Cancel|MenuAction_End);
	GetSkillDesc(skillid, display, sizeof(display), client);
	SetMenuTitle(menu, display);
	
	AddMenuItem(menu, "", " ", ITEMDRAW_SPACER);
	
	//SetMenuExitBackButton(menu, true);
	//SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuDescSkill(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_Cancel)
	{
		if(param2 == MenuCancel_ExitBack)
			DisplayMenu(BuildMenuDesc(client), client, MENU_TIME_FOREVER);
	}
	else if(action == MenuAction_End)
		CloseHandle(menu);
}

stock Handle:BuildMenuRPG(client)
{
	//decl String:display[256];
	new Handle:menu = CreateMenu(HandlerMenuRPG);
	SetMenuTitle(menu, "%T", "What is an RPG? title", client);
	
	AddMenuItem(menu, " ", " ", ITEMDRAW_SPACER);
	
	//SetMenuExitBackButton(menu, true);
	//SetMenuExitButton(menu, true);
	
	return menu;
}

public HandlerMenuRPG(Handle:menu, MenuAction:action, client, param2)
{
	if(action == MenuAction_End)
		CloseHandle(menu);
}

// -------------------------------------------------------------------------------------------------------------------------
AddMenuPlayers(Handle:menu, client = 0, bool:alive = false)
{
	new count = 0;
	decl String:buffer[64], String:userid[16];
	for(new i = 1; i <= MaxClients; i++)
	{
		if(i == client)
			continue;
		
		if(!IsValidPlayer(i))
			continue;
		
		if(alive && !IsPlayerAlive(i))
			continue;
		
		IntToString(GetClientUserId(i), userid, sizeof(userid));
		Format(buffer, sizeof(buffer), "%T", "Player", client, userid, i);
		AddMenuItem(menu, userid, buffer);
		count++;
	}
	return count;
}
// -------------------------------------------------------------------------------------------------------------------------
Action:API_OnSkillUP(&client, &skillid, &old_value, &new_value)
{
	Call_StartForward(hFWD_OnSkillUP);
	
	Call_PushCellRef(client);
	Call_PushCellRef(skillid);
	Call_PushCellRef(old_value);
	Call_PushCellRef(new_value);
	
	new Action:result;
	Call_Finish(result);
	return result;
}

public Native_OnSkillUP(Handle:plugin, numParams)
{
	new client = GetNativeCell(1);
	new skillid = GetNativeCell(2);
	new old_value = GetNativeCell(3);
	new new_value = GetNativeCell(4);
	return _:API_OnSkillUP(client, skillid, old_value, new_value);
}